using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Box2D.XNA;
using Spinning.Spinning.Unitity;
using Microsoft.Xna.Framework;

namespace Spinning.Spinning.Entity
{
    class PhysicSprite : AnimationSprite
    {
        public delegate void OnContactHandler(PhysicSprite me, PhysicSprite other);
        public OnContactHandler OnBeginContactEvent, OnEndContactEvent;
        public Body body;
        protected Fixture _fixture;

        public Filter Filter
        {
            set
            {
                if (_fixture != null)
                {
                    Filter filter;
                    _fixture.GetFilterData(out filter);
                    filter.categoryBits = value.categoryBits; ;
                    filter.maskBits = value.maskBits;
                    filter.groupIndex = value.groupIndex;
                    _fixture.SetFilterData(ref filter);
                }
            }
            get
            {
                if (_fixture != null)
                {
                    Filter f;
                    _fixture.GetFilterData(out f);
                    return f;
                }
                else throw new Exception();
            }
        }

        public bool IsSensor
        {
            get
            {
                bool t = false;
                if (_fixture != null)
                    t = _fixture.IsSensor();
                return t;
            }
            set
            {
                if (_fixture != null)
                    _fixture.SetSensor(value);
            }
        }

        public enum PhysicType
        {
            Player, Enemy, Marble, Default, Boss, Item, Barrier, WindBlade
        }

        public PhysicType Physic_Type { get; protected set; }

        public PhysicSprite()
        {
            Filter = new Filter();
            Physic_Type = PhysicType.Default;
        }

        //must call after onLoad
        public virtual void OnCreatBody(World world, PhysicConnectManager connectManager)
        {
            BodyDef bd = new BodyDef();
            bd.type = BodyType.Dynamic;
            body = world.CreateBody(bd);
            FixtureDef fd = new FixtureDef();
            CircleShape cs = new CircleShape();
            cs._radius = _frameSize.Y / 2.45f / Constants.MeterToPixal;
            fd.shape = cs;
            _fixture = body.CreateFixture(fd);
            body.SetTransform(Vector2.Zero, 0);
            PhysicConnector connector = new PhysicConnector(this, body);
            connectManager.AddPhysicConnector(connector);
        }

        //public override Vector2 Position
        //{
        //    get
        //    {
        //        if (body == null)
        //            return base.Position;
        //        else
        //            return BodyPosiotion;
        //    }
        //    set
        //    {
        //        base.Position = value;
        //        if (body != null)
        //            BodyPosiotion = value;
        //    }
        //}

        public override float Rotation
        {
            get
            {
                return base.Rotation;
            }
            set
            {

                base.Rotation = value;
                if (body != null)
                    BodyRotation = value;
            }
        }

        protected float BodyRotation
        {
            get
            {
                return body.Rotation;
            }
            set
            {
                body.SetTransform(body.Position, value);
            }
        }

        public Vector2 BodyPosiotion
        {
            set
            {
                Vector2 pos = Functional.Vector2InWorld(value);
                body.SetTransform(pos, 0);
                Position = value;
            }
            get
            {
                return Functional.Vector2InScene(body.GetPosition());
            }
        }

        public virtual void BeginContact(PhysicSprite other)
        {
            if (OnBeginContactEvent != null)
                OnBeginContactEvent(this, other);
        }

        public virtual void EndContact(PhysicSprite other)
        {
            if (OnEndContactEvent != null)
                OnEndContactEvent(this, other);
        }

    }
}
